﻿#region GNU General Public License
/*
-----------------------------------------------------------------------------
This source file is part of jscc
    (Javascript with Classes)
For the latest info, see http://code.google.com/p/jscc

Copyright (c) 2011 Tapani Valkonen

jscc is free software: you can redistribute it and/or modify it under 
the terms of the GNU General Public License as published by the 
Free Software Foundation, either version 3 of the License, or (at your option)
any later version. 
 
jscc is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
for more details.

You should have received a copy of the GNU General Public License 
along with jscc. If not, see http://www.gnu.org/licenses/.
-----------------------------------------------------------------------------
*/
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using jscc.Ast;
using System.IO;

namespace jscc
{
    class Program
    {
        static void PrintHelp()
        {
            Version v = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
            Console.WriteLine("jscc v" + v.Major + "." + v.Minor);
            Console.WriteLine();
            Console.WriteLine("Available parameters are:");

            Console.WriteLine("-h or --help             Print this help text");
            Console.WriteLine("-o filename              Define the filename of the output file");
            Console.WriteLine("-v or --verbose          Print more verbose output");

        }

        static void Main(string[] args)
        {
            bool verbose = false;
            string output = "";

            List<string> inputs = new List<string>();

            for (int i = 0; i < args.Length; i++)
            {
                string arg = args[i];

                if (arg == "-o" && args.Length > i-1)
                {
                    if (!string.IsNullOrEmpty(output))
                    {
                        Console.WriteLine("Output already defined");
                        return;
                    }

                    i++;
                    output = args[i];
                    continue;
                }
                else if(arg == "-h" || arg == "--help")
                {
                    PrintHelp();
                    return;
                }
                else if (arg == "-v" || arg == "--verbose")
                {
                    verbose = true;
                }
                else
                {
                    inputs.Add(arg);
                }
            }

            if (string.IsNullOrEmpty(output))
            {
                Console.WriteLine("Output file not defined");
                return;
            }

            if (inputs.Count <= 0)
            {
                Console.WriteLine("No input files defined");
                return;
            }

            if (System.IO.File.Exists(output)) System.IO.File.Delete(output);

            foreach (string input in inputs)
            {
                ProcessFile(input, output, verbose);
            }
        }

        public static void ProcessFile(string input, string output, bool verbose)
        {
            Scanner scanner = new Scanner();
            TextReader reader = new StreamReader(input);
            TokenStream stream = scanner.Scan(input, reader.ReadToEnd());
            reader.Close();

            if (verbose)
            {
                foreach (Token item in stream.Tokens)
                {
                    if (item.Keyword != KeywordType.None)
                        Console.WriteLine(String.Format("{0} {1}:{2}", item.Data, item.Type, item.Keyword));
                    else
                        Console.WriteLine(String.Format("{0} {1}", item.Data, item.Type));
                }
            }

            Parser parser = new Parser(stream);
            AstNode root = parser.Parse();

            if (verbose)
            {
                AstPrintVisitor visitor = new AstPrintVisitor();
                root.Accept(visitor);
            }

            Generator gen = new Generator();
            gen.Generate(root, output);

            if (verbose)
            {
                gen.PrintFiles();
            }

            gen.WriteFiles();
        }
    }
}
